package com.haiyuancloud.base.deal.ctr;

import com.github.tobato.fastdfs.domain.fdfs.MetaData;
import com.haiyuancloud.base._enum.BaseDealCoreEnum;
import com.haiyuancloud.base.file.core.chain.model.ChainFileUploadResultModel;
import com.haiyuancloud.base.file.core.chain.plugin.FileStorageChainPluginService;
import com.haiyuancloud.base.file.entity.TbBaseFileDownEntity;
import com.haiyuancloud.base.file.entity.TbBaseFileUploadEntity;
import com.haiyuancloud.base.file.select.map.service.SelectMapTbBaseFileDownService;
import com.haiyuancloud.base.file.select.map.service.SelectMapTbBaseFileUploadService;
import com.haiyuancloud.base.file.update.service.UpdateTbBaseFileUploadService;
import com.haiyuancloud.common.core.model.ContentTypeModel;
import com.haiyuancloud.db.core.model.DsDataModel;
import com.haiyuancloud.util.ObjectUtil;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

@RestController
@RequestMapping("/file/ctr")
public class FileCtr extends BaseCtr {

    /***
     * 日志打印
     */
    private static Logger logger = LoggerFactory.getLogger(FileCtr.class);

    @Resource
    private SelectMapTbBaseFileDownService selectMapTbBaseFileDownService;

    @Resource
    private SelectMapTbBaseFileUploadService selectMapTbBaseFileUploadService;

    @Resource
    private UpdateTbBaseFileUploadService updateTbBaseFileUploadService;

    @Resource
    private FileStorageChainPluginService fileStorageChainPluginService;

    @GetMapping("/view/{ID}")
    public void view(@PathVariable(value = "ID") String ID, HttpServletResponse response) throws IOException {
        OutputStream os = null;
        String S_FILE_NAME = "";
        String S_DOWN_PATH = "";
        DsDataModel dsDataModel = getDsDataModel();
        TbBaseFileUploadEntity tbBaseFileUploadEntity = new TbBaseFileUploadEntity();
        tbBaseFileUploadEntity.setId(ObjectUtil.toLong(ID));
        TbBaseFileUploadEntity baseFileUploadEntity = (TbBaseFileUploadEntity) selectMapTbBaseFileUploadService.map(dsDataModel.getTENANT_DEAL_DS_ID(),tbBaseFileUploadEntity);
        S_FILE_NAME = baseFileUploadEntity.getFileName();
        S_DOWN_PATH = baseFileUploadEntity.getFilePath();
        ContentTypeModel contentTypeModel = ObjectUtil.getContentType(S_FILE_NAME);
        FileUtils.readFileToByteArray(getDictionaryFile(S_DOWN_PATH));
        BufferedImage bufferedImage = ImageIO.read(getDictionaryFile(S_DOWN_PATH));
        response.setContentType(contentTypeModel.getContentType());
        os = response.getOutputStream();
        if(ObjectUtil.isNotNull(bufferedImage)){
            ImageIO.write(bufferedImage,contentTypeModel.getExt(),os);
        }
    }

    @PostMapping("/export/{S_ID}")
    public ResponseEntity<byte[]> export(@PathVariable(value = "S_ID") Long S_ID, HttpServletRequest request) throws IOException {
        DsDataModel dsDataModel = getDsDataModel();

        TbBaseFileUploadEntity tbBaseFileUploadEntity = new TbBaseFileUploadEntity();
        tbBaseFileUploadEntity.setId(S_ID);
        TbBaseFileUploadEntity baseFileUploadEntity = (TbBaseFileUploadEntity) selectMapTbBaseFileUploadService.map(dsDataModel.getTENANT_DEAL_DS_ID(),tbBaseFileUploadEntity);

        String S_FILE_NAME = baseFileUploadEntity.getFileName();
        String S_DOWN_PATH = baseFileUploadEntity.getFilePath();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", getFileName(S_FILE_NAME, request));
        return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(getDictionaryFile(S_DOWN_PATH)),
                headers, HttpStatus.OK);

    }

    @PostMapping("/download/{ID}")
    public ResponseEntity<byte[]> download(@PathVariable(value = "ID") Long ID, HttpServletRequest request) throws IOException {
        String S_FILE_NAME = "";
        String S_DOWN_PATH = "";
        DsDataModel dsDataModel = getDsDataModel();
        TbBaseFileUploadEntity tbBaseFileUploadEntity = new TbBaseFileUploadEntity();
        tbBaseFileUploadEntity.setId(ID);
        TbBaseFileUploadEntity baseFileUploadEntity = (TbBaseFileUploadEntity) selectMapTbBaseFileUploadService.map(dsDataModel.getTENANT_DEAL_DS_ID(),tbBaseFileUploadEntity);
        if(ObjectUtil.isNull(baseFileUploadEntity)){
            TbBaseFileDownEntity tbBaseFileDownParamEntity = new TbBaseFileDownEntity();
            tbBaseFileDownParamEntity.setS_ID(ID);
            TbBaseFileDownEntity tbBaseFileDownEntity = (TbBaseFileDownEntity)selectMapTbBaseFileDownService.map(dsDataModel.getTENANT_DEAL_DS_ID(),tbBaseFileDownParamEntity);
            S_FILE_NAME = tbBaseFileDownEntity.getS_FILE_NAME();
            S_DOWN_PATH = tbBaseFileDownEntity.getS_DOWN_PATH();
        }else{
             S_FILE_NAME = baseFileUploadEntity.getFileName();
             S_DOWN_PATH = baseFileUploadEntity.getFilePath();
        }

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", getFileName(S_FILE_NAME, request));
        return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(getDictionaryFile(S_DOWN_PATH)),
                headers, HttpStatus.OK);

    }

    @PostMapping("/delete/{ID}")
    public Map<String,Object> delete(@PathVariable(value = "ID") Long ID, HttpServletRequest request) throws IOException {
        DsDataModel dsDataModel = getDsDataModel();
        TbBaseFileUploadEntity tbBaseFileUploadEntity = new TbBaseFileUploadEntity();
        tbBaseFileUploadEntity.setId(ID);
        tbBaseFileUploadEntity.setFileFlag(BaseDealCoreEnum.I_FLAG.DEL.getValue());
        tbBaseFileUploadEntity.setTENANT_ID(dsDataModel.getTENANT_ID());
        tbBaseFileUploadEntity.setCREATE_PARTITION(dsDataModel.getTENANT_PARTITION());
        updateTbBaseFileUploadService.update(dsDataModel.getTENANT_DEAL_DS_ID(),tbBaseFileUploadEntity);
        return this.getDefaultResultData();
    }


    @PostMapping("/upload")
    public Object upload( @RequestParam  Map<String, Object> submitParam, HttpServletRequest request){
        Map<String,Object> tmpData = new HashMap<>();
        DsDataModel dsDataModel = this.getDsDataModel();
        List<Map<String,Object>> uploadList = new ArrayList();
        if(ObjectUtil.isNull(submitParam)){
            submitParam =  new HashMap<>();
        }
        Map<String, Object> resultData = this.getDefaultResultData();
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        if(multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            Iterator<String> ite = multiRequest.getFileNames();
            while (ite.hasNext()) {
                MultipartFile file = multiRequest.getFile(ite.next());
                if (ObjectUtil.isNotNull(file)) {
                    Set<MetaData> metaDataSet = null;
                    ChainFileUploadResultModel chainFileUploadResultModel = null;
                    try {
                        chainFileUploadResultModel = fileStorageChainPluginService.uploadFile( dsDataModel,file.getInputStream(),file.getOriginalFilename(),  file.getSize(),  metaDataSet,submitParam);
                    } catch (IOException e) {
                        logger.error("异常输出:"+e.getMessage(),e);
                    }

                    tmpData.put("uid",chainFileUploadResultModel.getS_ID());
                    tmpData.put("name",chainFileUploadResultModel.getS_FILE_NAME());
                    tmpData.put("status","done");
                    tmpData.put("url","");
                    tmpData.put("thumbUrl","");
                    Map<String,Object> d =(Map<String,Object>) ObjectUtil.clone(tmpData);
                    uploadList.add(d);
                }
            }
        }
        resultData.put("data",uploadList);
        Map<String,Object> d = new HashMap<>();
        d.put("file",tmpData);
        d.put("fileList",uploadList);
        return d;
    }



    private File getDictionaryFile(String fileName){
        return  new File(fileName);
    }

    private String getFileName(String filePath, HttpServletRequest request) throws UnsupportedEncodingException {
        String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
        String Agent = request.getHeader("User-Agent");
        if (null != Agent) {
            Agent = Agent.toLowerCase();
            if (Agent.indexOf("firefox") != -1) {
                fileName = new String(fileName.getBytes(), "iso8859-1");
            } else if (Agent.indexOf("msie") != -1) {
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } else {
                fileName = URLEncoder.encode(fileName, "UTF-8");
            }
        }
        return fileName;
    }

}
